﻿using PLCSharp.Command;

namespace PLCSharp.FB.Cyl
{
    public class FB_Cyl
    {
        /// <summary>
        /// 气缸名称
        /// </summary>
        public string? strName { get; private set; }

        /// <summary>
        /// 原位感应
        /// </summary>
        public bool bHPSensor { get; private set; }

        /// <summary>
        /// 工作位感应
        /// </summary>
        public bool bWPSensor { get; private set; }

        /// <summary>
        /// 超时时间HP
        /// </summary>
        public double tHPOverTime { get; private set; }

        /// <summary>
        ///  超时时间HP
        /// </summary>
        public double tWPOverTime { get; private set; }

        /// <summary>
        /// 气缸指令
        /// </summary>
        public EM_CylCmd i_CylCmd { get; private set; }

        /// <summary>
        /// 原位输出
        /// </summary>
        public bool o_bHPOut { get; private set; }

        /// <summary>
        /// 工作位输出
        /// </summary>
        public bool o_bWPOut { get; private set; }

        /// <summary>
        /// 报警
        /// </summary>
        public ST_CylErr o_CylErr { get; } = new ST_CylErr();

        private readonly TON tonHPSensor = new();
        private readonly TON tonWPSensor = new();
        private readonly TON tonHPTimer = new();
        private readonly TON tonWPTimer = new();

        /// <summary>
        /// 原位感应器的线号
        /// </summary>
        public string? i_strHP { get; set; }

        public string? i_strWP { get; set; }

        /// <summary>
        /// 原位互锁
        /// </summary>
        public bool i_bInterLock_HP { get; set; }

        /// <summary>
        /// 工作位互锁
        /// </summary>
        public bool i_bInterLock_WP { get; set; }

        /// <summary>
        /// 互锁时提示的信息
        /// </summary>
        public string? i_strInterLock_HP { get; set; }

        /// <summary>
        ///  互锁时提示的信息
        /// </summary>
        public string? i_strInterLock_WP { get; set; }

        /// <summary>
        /// 块初始化
        /// </summary>
        private bool Init;

        /// <summary>
        /// 没有感应的气缸
        /// </summary>
        /// <param name="i_strName">气缸名称</param>
        /// <param name="i_tonHPSensor">原位已到达信号延时</param>
        /// <param name="i_tonWPSensor">工作位已到达信号延时</param>
        public void FB(string? i_strName,
            double i_tonHPSensor,
            double i_tonWPSensor)
        {
            if (!Init)
            {
                Init = true;
                strName = i_strName;
                o_CylErr.astrErr[3] = strName + "原位互锁中，" + i_strInterLock_HP;
                o_CylErr.astrErr[4] = strName + "工作位互锁中，" + i_strInterLock_WP;
            }
            tonHPSensor.FB(o_bHPOut, i_tonHPSensor);
            bHPSensor = tonHPSensor.Q;

            tonWPSensor.FB(o_bWPOut, i_tonWPSensor);
            bWPSensor = tonWPSensor.Q;

            Out();
        }

        /// <summary>
        /// 只有原位感应的气缸
        /// </summary>
        /// <param name="i_strName">气缸名称</param>
        /// <param name="i_tHPOverTime">原位超时时间</param>
        /// <param name="i_bHPSensor">原位感应</param>
        /// <param name="i_tonWPSensor">工作位已到达信号延时</param>
        public void FB(string? i_strName,
             double i_tHPOverTime,
            bool i_bHPSensor,
            double i_tonWPSensor)
        {
            if (!Init)
            {
                Init = true;
                strName = i_strName;
                o_CylErr.astrErr[0] = strName + "原位超时 " + i_strHP;
                o_CylErr.astrErr[1] = strName + "工作位超时 " + i_strWP;
                o_CylErr.astrErr[2] = strName + "感应同时亮起异常 " + i_strHP + " " + i_strWP;
                o_CylErr.astrErr[3] = strName + "原位互锁中，" + i_strInterLock_HP;
                o_CylErr.astrErr[4] = strName + "工作位互锁中，" + i_strInterLock_WP;
                tHPOverTime = i_tHPOverTime;
            }

            bHPSensor = i_bHPSensor;

            tonWPSensor.FB(o_bWPOut, i_tonWPSensor);
            bWPSensor = tonWPSensor.Q;

            Out();
            //超时
            tonHPTimer.FB(o_bHPOut && !i_bHPSensor, this.tHPOverTime);
            o_CylErr.abErr[0] = tonHPTimer.Q;
        }

        /// <summary>
        /// 只有工作位感应的气缸
        /// </summary>
        /// <param name="i_strName">气缸名称</param>
        /// <param name="i_tonHPSensor">原位已到达信号延时</param>
        /// <param name="i_tWPOverTime">工作位超时时间</param>
        /// <param name="i_bWPSensor">工作位感应</param>
        public void FB(string? i_strName,
             double i_tonHPSensor,
             double i_tWPOverTime,
            bool i_bWPSensor
            )
        {
            if (!Init)
            {
                Init = true;
                strName = i_strName;
                o_CylErr.astrErr[0] = strName + "原位超时 " + i_strHP;
                o_CylErr.astrErr[1] = strName + "工作位超时 " + i_strWP;
                o_CylErr.astrErr[2] = strName + "感应同时亮起异常 " + i_strHP + " " + i_strWP;
                o_CylErr.astrErr[3] = strName + "原位互锁中，" + i_strInterLock_HP;
                o_CylErr.astrErr[4] = strName + "工作位互锁中，" + i_strInterLock_WP;
                tWPOverTime = i_tWPOverTime;
            }

            bWPSensor = i_bWPSensor;

            tonHPSensor.FB(o_bHPOut, i_tonHPSensor);
            bHPSensor = tonHPSensor.Q;

            Out();
            //超时
            tonWPTimer.FB(o_bWPOut && !i_bWPSensor, this.tWPOverTime);
            o_CylErr.abErr[1] = tonWPTimer.Q;
        }

        /// <summary>
        /// 两个感应的气缸
        /// </summary>
        /// <param name="i_strName">气缸名</param>
        /// <param name="i_tHPOverTime">原位超时</param>
        /// <param name="i_tWPOverTime">工作位超时</param>
        /// <param name="i_bHPSensor">原位感应</param>
        /// <param name="i_bWPSensor">工作位感应</param>
        public void FB(
            string? i_strName,
            double i_tHPOverTime,
            double i_tWPOverTime,
            bool i_bHPSensor,
            bool i_bWPSensor
    )
        {
            //初始化气缸
            if (!Init)
            {
                Init = true;
                this.strName = i_strName;
                o_CylErr.astrErr[0] = this.strName + "原位超时 " + i_strHP;
                o_CylErr.astrErr[1] = this.strName + "工作位超时 " + i_strWP;
                o_CylErr.astrErr[2] = this.strName + "感应同时亮起异常 " + i_strHP + " " + i_strWP;
                o_CylErr.astrErr[3] = this.strName + "原位互锁中，禁止移动，" + i_strInterLock_HP;
                o_CylErr.astrErr[4] = this.strName + "工作位互锁中，禁止移动，" + i_strInterLock_WP;
                this.tHPOverTime = i_tHPOverTime;
                this.tWPOverTime = i_tWPOverTime;
            }

            this.bHPSensor = i_bHPSensor;
            this.bWPSensor = i_bWPSensor;

            Out();

            //超时

            tonHPTimer.FB(o_bHPOut && !i_bHPSensor, this.tHPOverTime);
            tonWPTimer.FB(o_bWPOut && !i_bWPSensor, this.tWPOverTime);

            o_CylErr.abErr[0] = tonHPTimer.Q;
            o_CylErr.abErr[1] = tonWPTimer.Q;
        }

        private void Out()
        {
            //根据指令设置输出
            switch (i_CylCmd)
            {
                case EM_CylCmd.NOP:
                    o_bHPOut = false;
                    o_bWPOut = false;
                    break;

                case EM_CylCmd.HP:
                    o_bWPOut = false;
                    if (i_bInterLock_HP)
                    {
                        o_bHPOut = true;
                    }
                    else
                    {
                        o_CylErr.abErr[3] = true;
                        o_bHPOut = false;
                    }

                    break;

                case EM_CylCmd.WP:
                    o_bHPOut = false;
                    if (i_bInterLock_WP)
                    {
                        o_bWPOut = true;
                    }
                    else
                    {
                        o_CylErr.abErr[4] = true;
                        o_bWPOut = false;
                    }
                    break;

                case EM_CylCmd.Stop:
                    o_bHPOut = false;
                    o_bWPOut = false;
                    break;

                default:
                    break;
            }
        }
    }
}